package com.study.sbsummary.utils;

import java.math.BigDecimal;
import java.util.function.Supplier;
import java.util.regex.Pattern;

public class ParamsValid {
    private ParamErrorType returnCode;
    private String message;

    public ParamErrorType getReturnCode() {
        return this.returnCode;
    }

    public void setReturnCode(ParamErrorType returnCode) {
        this.returnCode = returnCode;
    }

    public String getMessage() {
        return this.message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public ParamsValid() {
        this.returnCode = ParamErrorType.Success;
    }

    public ParamsValid validNotNull(String paramName, Object paramValue) {
        return this.verifyNull(paramName, () -> {
            return paramValue != null;
        });
    }

    public ParamsValid validNotNullOrEmpty(String paramName, String paramValue) {
        return this.verifyNull(paramName, () -> {
            return this.isNotEmpty(paramValue);
        });
    }

    public ParamsValid validMoreThenZero(String paramName, Integer paramValue) {
        return this.verifyError(paramName, () -> {
            return paramValue != null && paramValue > 0;
        });
    }

    public ParamsValid valid(String paramName, Supplier<Boolean> booleanSupplier) {
        return this.verifyNull(paramName, booleanSupplier);
    }

    public ParamsValid valid(String paramName, Boolean isBoolean) {
        return this.verifyNull(paramName, () -> {
            return isBoolean;
        });
    }

    public ParamsValid validRange(String name, int value, int min, int max) {
        String alert;
        if (min == 2147483647) {
            alert = String.format("%s值必须小于等于 %s", name, max);
        } else if (max == 2147483647) {
            alert = String.format("%s值必须大于等于 %s", name, min);
        } else {
            alert = String.format("%s值必须在 [%s~%s] 之间", name, min, max);
        }

        return this.verify(ParamErrorType.ArgumentError, alert, () -> {
            return value >= min && value <= max;
        });
    }

    public ParamsValid validMatchPattern(String name, String value, String pattern) {
        String alert = String.format("%s必须满足格式：%s", name, pattern);
        return this.verify(ParamErrorType.ArgumentError, alert, () -> {
            return Pattern.matches(pattern, value);
        });
    }

    public ParamsValid validTelNumber(String phone) {
        String alert = "电话号码格式不正确";
        return this.verify(ParamErrorType.ArgumentError, alert, () -> {
            return this.isPhoneNumber(phone);
        });
    }

    public ParamsValid validMobile(String mobile) {
        String alert = "手机号码格式不正确";
        return this.verify(ParamErrorType.ArgumentError, alert, () -> {
            return this.isMobile(mobile);
        });
    }

    private boolean isPhoneNumber(String phone) {
        String regexMobile = "^1\\d{10}$";
        String regexPhone = "^((0\\d{2,3})-)(\\d{7,8})(-(\\d{3,}))?$";
        return this.isNotEmpty(phone) && (Pattern.matches("^1\\d{10}$", phone) || Pattern.matches("^((0\\d{2,3})-)(\\d{7,8})(-(\\d{3,}))?$", phone));
    }

    private boolean isMobile(String mobile) {
        String regexMobile = "^1\\d{10}$";
        return this.isNotEmpty(mobile) && Pattern.matches("^1\\d{10}$", mobile);
    }

    public ParamsValid validCoordinate(BigDecimal lon, BigDecimal lat, boolean checkNull) {
        String alert = "经纬度数值超出范围(minX=-180.0,maxX=180.0,minY=-90.0,maxY=90.0)";
        return this.verify(ParamErrorType.ArgumentError, alert, () -> {
            return CoordinateUtil.valid(lon, lat, checkNull);
        });
    }

    public ParamsValid validIp(String ip) {
        String alert = "ip地址格式不正确";
        return this.verify(ParamErrorType.ArgumentError, alert, () -> {
            return IpUtil.verifyIp(ip);
        });
    }

    public ParamsValid validIntArrayString(String alert, String intArrayString, String separator) {
        return this.verify(ParamErrorType.ArgumentError, alert, () -> {
            return IntegerExtension.isIntArray(intArrayString, separator);
        });
    }

    public boolean isValid() {
        return this.returnCode == ParamErrorType.Success && this.isEmpty(this.message);
    }

    public <T> Protocol<T> showInValidMessage() {
        return new Protocol(this.returnCode.getCode(), this.message);
    }

    public ParamsValid verifyNull(String name, Supplier<Boolean> valid) {
        String alert = ParamErrorType.MissRequireArgument.getMessage() + ":" + name;
        return this.verify(ParamErrorType.MissRequireArgument, alert, valid);
    }

    public ParamsValid verifyError(String name, Supplier<Boolean> valid) {
        String alert = ParamErrorType.ArgumentError.getMessage() + ":" + name;
        return this.verify(ParamErrorType.ArgumentError, alert, valid);
    }

    public ParamsValid verify(ParamErrorType code, Supplier<Boolean> valid) {
        return this.verify(code, (String)null, valid);
    }

    public ParamsValid verify(ParamErrorType code, String message, Supplier<Boolean> valid) {
        if (this.isValid() && !(Boolean)valid.get()) {
            this.returnCode = code;
            this.message = this.isEmpty(message) ? code.getMessage() : message;
        }

        return this;
    }

    private boolean isEmpty(String msg) {
        return msg == null || msg.length() == 0;
    }

    private boolean isNotEmpty(String msg) {
        return !this.isEmpty(msg);
    }
}
